package main

import (
	"example_1/flyweight"
	"fmt"
	"math/rand"
	"runtime"
	"sync"
	"time"
)

func main() {
	runTeslaMap := map[string]*flyweight.RunTesla{}
	mutex := sync.Mutex{}
	wg := sync.WaitGroup{}
	for i := 0; i < 1000000; i++ {
		wg.Add(1)
		go func(j int) {
			vin := fmt.Sprintf("tesla-%d", j)
			tesla := flyweight.NewTesla(vin, "灰", "model3", "big", "宁德时代")
			runTesla := flyweight.NewRunTesla(tesla)
			mutex.Lock()
			defer func() {
				mutex.Unlock()
				wg.Done()
			}()

			runTeslaMap[tesla.Vin] = runTesla
		}(i)
	}
	wg.Wait()

	for {
		rand.Seed(time.Now().UnixNano())
		randomNum := rand.Intn(1000000)

		runTesla := runTeslaMap[fmt.Sprintf("tesla-%d", randomNum)]
		runTesla.SetPos(&flyweight.Position{
			LatX: 121.1,
			LatY: 112.1,
		})
		runTesla.SetSpeed(110.6)
		time.Sleep(time.Second * 10)
		printMem()
	}

}

// 不使用享元模式，内存占用: Alloc = 322 MiB	TotalAlloc = 409 MiB	Sys = 794 MiB	NumGC = 11
// 使用享元模式，内存占用: Alloc = 237 MiB	TotalAlloc = 406 MiB	Sys = 576 MiB	NumGC = 14

func printMem() {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)

	// 将字节数转换为MB
	fmt.Printf("Alloc = %v MiB", m.Alloc/1024/1024)             // 当前堆对象分配的内存
	fmt.Printf("\tTotalAlloc = %v MiB", m.TotalAlloc/1024/1024) // 累计为堆对象分配的总内存
	fmt.Printf("\tSys = %v MiB", m.Sys/1024/1024)               // 从操作系统获得的内存总量
	fmt.Printf("\tNumGC = %v\n", m.NumGC)                       // 垃圾回收次数
}
